package main

import (
	"fmt"
	"math/rand"
	"time"
)

/**
 * nil channel 可以正确运行,但是select不到 会阻塞住
 */
func main() {
	var c1, c2 = generator(), generator()

	worker := createWorker(0)

	// 将values 收下来排队
	var values []int

	// 计时器
	tm := time.After(10 * time.Second) // 返回chan  time

	// 定时任务,查看队列积压
	tick := time.Tick(time.Second) // 每秒钟看下队列长度
	for {
		var activeWorker chan<- int
		var activeValue int
		if len(values) > 0 { // 有值
			activeWorker = worker
			activeValue = values[0]
		}
		select {
		case n := <-c1:
			values = append(values, n) // 排队
		case n := <-c2:
			values = append(values, n)
		case activeWorker <- activeValue:
			values = values[1:] // 将第一个拿掉
		case <-time.After(800 * time.Millisecond): // 每次select花费时间,每两次生成数据时间差超过800ms，会中断
			fmt.Println("timeout")
		case <-tick:
			fmt.Println(
				"queue len =", len(values))
		case <-tm:
			fmt.Println("bye")
			return
		}
	}

}

func generator() chan int {
	out := make(chan int)
	go func() {
		i := 0
		for {
			// 随机sleep, 消耗数据过慢，中间数据会被冲掉
			time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond)
			out <- i
			i++
		}
	}()
	return out
}

func worker(id int, c chan int) {
	for n := range c {
		time.Sleep(time.Second) // 每秒钟消耗一个,每1500有两个人生成数据
		fmt.Printf("Worker %d received %d\n",
			id, n)
	}
}

func createWorker(id int) chan<- int {
	c := make(chan int)
	go worker(id, c)
	return c
}
